﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace SpriteEditor
{
    public class Frame : SpriteCalculation
    {
        public static Sprite sprite = frmMain.spr;
        public Frame()
        {
            if (sprite == null)
            {
                sprite = new Sprite();
                sprite = frmMain.spr;
            }
        }
        public int Index { get; set; }
        public int ID { get; set; }
        public int X { get; set; }
        public int Y { get; set; }
        public int W { get; set; }
        public int H { get; set; }
        public string Desc { get; set; }

        public Bitmap img { get; set; }

        public int NumOfModules { get; set; }
        public List<ModulesOfFrame> lst_ModulesOfFrame { get; set; }

        public Frame clone()
        {
            Frame newFrame = new Frame();

            newFrame.Index = this.Index;
            newFrame.ID = this.ID;
            newFrame.X = this.X;
            newFrame.Y = this.Y;
            newFrame.W = this.W;
            newFrame.H = this.H;
            newFrame.Desc = this.Desc;
            newFrame.NumOfModules = this.NumOfModules;

            //if (this.img != null)
            //    newAnim.img = this.img;

            if (this.lst_ModulesOfFrame != null)
            {
                newFrame.lst_ModulesOfFrame = new List<ModulesOfFrame>();
                for (int i = 0; i < lst_ModulesOfFrame.Count; i++)
                {
                    ModulesOfFrame m = new ModulesOfFrame();
                    m = lst_ModulesOfFrame[i].clone();
                    newFrame.lst_ModulesOfFrame.Add(m);
                }
            }
            newFrame.GenerateImage();

            return newFrame;
        }

        public int getModuleIndex(int ModuleID)
        {
            if (sprite.lst_Modules != null)
            {
                for (int i = 0; i < sprite.lst_Modules.Count; i++)
                {
                    if (sprite.lst_Modules[i].ID == ModuleID)
                        return i;
                }
            }
            return -1;
        }

        public Module getModuleFromIndex(int index)
        {
            return sprite.getModuleFromID(lst_ModulesOfFrame[index].ID);
        }

        public Module getModuleFromID(int ID)
        {
            return sprite.getModuleFromID(ID);
        }

        public void GenerateImage()
        {
            if (lst_ModulesOfFrame == null || sprite == null || sprite.lst_Modules == null)
            {
                img = null;
                return;
            }

            if (sprite.lst_Modules != null)
            {
                Point P1 = new Point(), P2 = new Point();

                P1.X = 9999;
                P1.Y = 9999;
                P2.X = -9999;
                P2.Y = -9999;

                for (int i = 0; i < lst_ModulesOfFrame.Count; i++)
                {
                    //int tmp_idxOfModule = getModuleIndex(lst_ModulesOfFrame[i].ID);

                    //if (tmp_idxOfModule != -1)
                    //{
                    //    if (lst_ModulesOfFrame[i].OX < P1.X)
                    //        P1.X = lst_ModulesOfFrame[i].OX;
                    //    if (lst_ModulesOfFrame[i].OY < P1.Y)
                    //        P1.Y = lst_ModulesOfFrame[i].OY;

                    //    if (lst_ModulesOfFrame[i].OX + lst_Modules[tmp_idxOfModule].W > P2.X)
                    //        P2.X = lst_ModulesOfFrame[i].OX + lst_Modules[tmp_idxOfModule].W;
                    //    if (lst_ModulesOfFrame[i].OY + lst_Modules[tmp_idxOfModule].W > P2.Y)
                    //        P2.Y = lst_ModulesOfFrame[i].OY + lst_Modules[tmp_idxOfModule].H;
                    //}

                    Module tmp_Module = getModuleFromID(lst_ModulesOfFrame[i].ID);

                    if (tmp_Module != null)
                    {
                        if (lst_ModulesOfFrame[i].OX < P1.X)
                            P1.X = lst_ModulesOfFrame[i].OX;
                        if (lst_ModulesOfFrame[i].OY < P1.Y)
                            P1.Y = lst_ModulesOfFrame[i].OY;

                        if (lst_ModulesOfFrame[i].OX + tmp_Module.W > P2.X)
                            P2.X = lst_ModulesOfFrame[i].OX + tmp_Module.W;
                        if (lst_ModulesOfFrame[i].OY + tmp_Module.W > P2.Y)
                            P2.Y = lst_ModulesOfFrame[i].OY + tmp_Module.H;
                    }
                }

                //Set this size
                X = P1.X;
                Y = P1.Y;
                W = P2.X - P1.X;
                H = P2.Y - P1.Y;

                if (W > 0 && H > 0)
                {
                    img = new Bitmap(W, H);
                    Graphics canvas = Graphics.FromImage(img);

                    for (int i = 0; i < lst_ModulesOfFrame.Count; i++)
                    {
                        //int tmp_idxOfModule = getModuleIndex(lst_ModulesOfFrame[i].ID);

                        //if (tmp_idxOfModule != -1)
                        //{
                        //    canvas.DrawImage(lst_Modules[tmp_idxOfModule].img, new Point(lst_ModulesOfFrame[i].OX - X, lst_ModulesOfFrame[i].OY - Y));
                        //}

                        bool isFlipHorizontally = lst_ModulesOfFrame[i].isFlipHorizontally();
                        bool flipVertically = lst_ModulesOfFrame[i].isFlipVertically();

                        Module tmp_Module = getModuleFromID(lst_ModulesOfFrame[i].ID);

                        if (tmp_Module != null)
                        {
                            canvas.DrawImage(FlipBitmap(tmp_Module.img, isFlipHorizontally, flipVertically),
                                            new Point(lst_ModulesOfFrame[i].OX - X, lst_ModulesOfFrame[i].OY - Y));
                        }
                    }
                }
                else
                {
                    img = null;
                }


            }
        }
    }

    public class ModulesOfFrame : SpriteCalculation
    {
        public int Index { get; set; }
        public int ID { get; set; }
        public int OX { get; set; }
        public int OY { get; set; }
        public String Frame_Flags { get; set; }

        public ModulesOfFrame clone()
        {
            ModulesOfFrame m = new ModulesOfFrame();
            m.Index = Index;
            m.ID = ID;
            m.OX = OX;
            m.OY = OY;
            m.Frame_Flags = Frame_Flags;
            return m;
        }

        public ModulesOfFrame()
        {
            OX = 0;
            OY = 0;
            Frame_Flags = "";

        }

        public int getFlags()
        {
            return XmlEngine.getFlagOfFrame_Int(Frame_Flags);
        }

        public void setFlags(int m_flag)
        {
            Frame_Flags = XmlEngine.getFlagOfFrame_String(m_flag);
        }

        public void addFlags(int m_flag)
        {
            int tmp_flags = XmlEngine.getFlagOfFrame_Int(Frame_Flags);
            Frame_Flags = XmlEngine.getFlagOfFrame_String(tmp_flags | m_flag);
        }

        public void removeFlags(int m_flag)
        {
            int tmp_flags = XmlEngine.getFlagOfFrame_Int(Frame_Flags);
            Frame_Flags = XmlEngine.getFlagOfFrame_String(tmp_flags & ~m_flag);
        }

        public void xorFlags(int m_flag)
        {
            int tmp_flags = XmlEngine.getFlagOfFrame_Int(Frame_Flags);
            Frame_Flags = XmlEngine.getFlagOfFrame_String(tmp_flags ^ m_flag);
        }

        public bool isFlipHorizontally()
        {
            return ((XmlEngine.getFlagOfFrame_Int(Frame_Flags) & XmlEngine.FLAG_FLIP_X) != 0);
        }

        public bool isFlipVertically()
        {
            return ((XmlEngine.getFlagOfFrame_Int(Frame_Flags) & XmlEngine.FLAG_FLIP_Y) != 0);
        }
    }
}
